/**
 * An abstract class that holds all the instance variables and method signatures that are going
 * to be implemented in the pieces in the chess game, where the pieces will be extensions of 
 * this abstract class.
 * 
 * @author Dzulhafizi Abidin
 */

package pieces;
import mainClasses.*;

public abstract class Piece{
	
	     
	protected int x;							//the x-coordinate of the piece
    protected int y;							//the y-coordinate of the piece
    protected int oldx;
    protected int oldy;
    public Board board;						//board used by the piece
    protected String type;						//variable to store the type of the piece (rook,queen,king,..etc)
    protected String side;						//variable to store the side of the piece (black or white)
    
    
    /** 
     * First constructor for abstract class Piece. It creates a piece with the coordinate of (xaxis,yaxis), sets the type to parameter
     * name and the color to parameter color, and puts it on board b. This constructor takes 6 different parameters.
     * 
     * @param xaxis - The X-axis coordinate of the piece on the board
     * @param yaxis - The Y-axis coordinate of the piece on the board
     * @param b - Board where the piece is going to be placed
     * @param isempty - boolean variable to determine a piece is empty or not
     * @param name - The type of the piece
     * @param color - The color of the piece, black or white
     */
    public Piece(int xaxis, int yaxis, Board b, String name, String color){
    	this.x=xaxis;
    	this.y=yaxis;
    	this.board=b;
    	this.type=name;
    	this.side=color;
    }   
    
    
    /** 
     * Second constructor for abstract class Piece. It creates an empty piece with the coordinate of (xaxis,yaxis)
     * and puts it on board b. It also initializes the 'empty' boolean variable to true. This constructor takes 3 different parameters.
     * 
     * @param xaxis - The X-axis coordinate of the empty piece on the board
     * @param yaxis - The Y-axis coordinate of the empty piece on the board
     * @param b - Board where the empty piece is going to be placed
     */
    public Piece(int xaxis, int yaxis, Board b)
    {
    	this.x=xaxis;
    	this.y=yaxis;
    	this.board=b;
    	this.type="Empty";
    }
    
   
    
    
    /**
     * Determines whether a piece (or an empty piece) at a given point p is from the same side(color) or not.
     * If the piece at p is from the opposite side, it returns true. It returns false if there's an opposite color
     * of piece or an empty piece at p.
     * 
     * @param p - Point on board 
     * @return A boolean value to determine there's an enemy or not
     */
    public boolean isEnemy(int otherX, int otherY)
    {
    	Piece p2 = this.board.getPiece(otherX, otherY);
    	if(this.getSide().equals(p2.getSide()))
    	{
    		return false;
    	}else if(p2.type.equals("         "))
    	{
    		return false;
    	}else
    	{
    		return true;
    	}
    }
    
    public String toString()
    {
    	String s = "";
    	s += " " + this.getClass().getName() + " (" + this.x + ", " + this.y + ") " + this.getSide();
    	return s;
    }
    
    /**
     * Accessor: Returns the current x-coordinate value of the piece
     * 
     * @return X-coordinate value of the piece on the board
     */
    public int getX(){return (int)this.x;}
    
    
    /**
     * Accessor: Returns the current y-coordinate value of the piece
     * 
     * @return Y-coordinate value of the piece on the board
     */
    public int getY(){return (int)this.y;}
    
    /**
     * Accessor: Returns the current x-coordinate value of the piece
     * 
     * @return X-coordinate value of the piece on the board
     */
    public int getoldX(){return (int)this.oldx;}
    
    
    /**
     * Accessor: Returns the current y-coordinate value of the piece
     * 
     * @return Y-coordinate value of the piece on the board
     */
    public int getoldY(){return (int)this.oldy;}
    
    
    /**
     * Accessor: Returns the type of the piece
     * 
     * @return Type of the piece
     */
    public String getType(){return this.type;}
    
    
    /**
     * Accessor: Returns the side/color of the piece
     * 
     * @return Side/color of the piece
     */
    public String getSide(){return this.side;}
    
    
    /**
     * Mutator: Sets the type of the piece to parameter s
     * 
     * @param s - The type that is going to be set on the piece
     */
    public void setType(String s)
    {
    	this.type = s;
    }
    
    
    /**
     * Determines whether a piece p2 is equal to this piece
     * 
     * @param p2 - a piece that is going to be compared
     * @return A boolean value to determine the equality of this piece and p2
     * 
     */
    public boolean isEqual(Piece p2)
    {
    	if(this.x==p2.getX() && this.y==p2.getY() && this.getClass().equals(p2.getClass()) && this.type==p2.getType() && this.side==p2.getSide())
    	{
    		return true;
    	}
    	return false;
    }
    
    
    /**
     * Moves (swap positions) the piece to the position of p2
     * 
     * @param p2 - a destination (Point) for a piece to move
     */
    public void move(int desX, int desY)
    {
    	this.oldx = this.x;
    	this.oldy = this.y;
    	this.board.swap(this.x, this.y, desX, desY);	
    }
    
    
    /**
     * Mutator: Changes the current position of the piece to position p2
     * 
     * @param p2 - new X and Y coordinates to be set on the piece
     */
    public void changePosition(int newX, int newY)
    {
    	this.oldx = this.x;
    	this.oldy = this.y;
    	this.x= newX;
    	this.y= newY;
    }
    
    
    /**
     * Determines whether it is possible for this piece to move to destination p2. This method will
     * be overwritten by all the classes that extends this abstract class because each piece has its
     * own valid move. It returns true if the move is valid and return false if it's an invalid move.
     * 
     * @param p2 - a destination (Point) for a piece to move
     * @return A boolean value to determine the validity of the move of the corresponding piece
     * 
     */
    public boolean movePossible(int x, int y)
    {
    	return false;
    }
    
}
